package sas

import (
	"strings"
	"time"

	"github.com/micro-plat/lib4go/security/md5"
	"github.com/micro-plat/lib4go/types"
)

//MD5Sign 生成签名，chain为参数间连接符，kv为键值间连接符
func (n *sasClient) MD5Sign(input types.XMap) (sign string, data types.XMap, err error) {
	input.SetValue(n.getTimespanName(), time.Now().Format("20060102150405"))
	input.SetValue(n.getEUIDName(), n.euid)
	return n.md5Sign(input)
}

func (n *sasClient) md5Sign(input types.XMap) (sign string, data types.XMap, err error) {
	//获取密钥
	res, err := n.SecretGet(MD5Str)
	if err != nil {
		return
	}
	return n.md5SignKey(input, res.Md5Secret)
}

func (n *sasClient) md5SignKey(input types.XMap, key string) (sign string, data types.XMap, err error) {
	//生成签名
	raw := n.buildRaw(input, key, MD5Str)
	sign = md5.Encrypt(raw)
	input.SetValue(n.getSignName(), sign)
	data = input
	return
}

//BuildMD5Sign 构建Md5签名结果
func (n *sasClient) BuildMD5Sign(input types.XMap) (sign string, data types.XMap, err error) {
	//获取密钥
	res, err := n.SecretGet(MD5Str)
	if err != nil {
		return
	}
	return n.md5SignKey(input, res.Md5Secret)
}

//VerifyMD5Sign 构建Md5签名结果
func (n *sasClient) VerifyMD5Sign(input types.XMap) (isMatch bool, err error) {
	//获取密钥
	res, err := n.SecretGet(MD5Str)
	if err != nil {
		return
	}
	outSign := input.GetString(n.getSignName())
	delete(input, n.getSignName())

	sign, _, err := n.md5SignKey(input, res.Md5Secret)
	if err != nil {
		return
	}
	if strings.EqualFold(outSign, sign) {
		return true, nil
	}
	return false, nil
}

//BuildMD5Sign 构建Md5签名结果
func (n *sasClient) BuildMD5SignWithRaw(raw string) (sign string, err error) {
	//获取密钥
	res, err := n.SecretGet(MD5Str)
	if err != nil {
		return
	}

	raw = n.spliceKey(raw, res.Md5Secret, MD5Str)
	return md5.Encrypt(raw), nil
}

//BuildMD5Sign 构建Md5签名结果
func (n *sasClient) VerifyMD5SignWithRaw(raw, outSign string) (isMatch bool, err error) {
	//获取密钥
	res, err := n.SecretGet(MD5Str)
	if err != nil {
		return
	}
	raw = n.spliceKey(raw, res.Md5Secret, MD5Str)
	sign := md5.Encrypt(raw)

	if strings.EqualFold(outSign, sign) {
		return true, nil
	}
	return false, nil
}
